"""
JWT工具类 - 用于生成和验证JSON Web Token
作者：资深Flask讲师
功能：
  1. encode: 生成JWT token
  2. decode: 解码并验证JWT token
"""

import jwt
from datetime import datetime, timedelta
from flask import current_app


class JWTUtil:
    """JWT工具类"""
    
    @staticmethod
    def encode(payload, expire_minutes=30):
        """
        生成JWT token
        
        参数:
            payload: dict - 载荷数据（如用户ID、用户名等）
            expire_minutes: int - 过期时间（分钟）
        
        返回:
            str - JWT token字符串
        """
        try:
            # 添加过期时间到载荷
            payload_copy = payload.copy()
            payload_copy['exp'] = datetime.utcnow() + timedelta(minutes=expire_minutes)
            payload_copy['iat'] = datetime.utcnow()  # 签发时间
            
            # 从配置中获取密钥
            secret_key = current_app.config.get('JWT_SECRET_KEY', 'your-secret-key-change-in-production')
            
            # 生成token
            token = jwt.encode(
                payload_copy,
                secret_key,
                algorithm='HS256'
            )
            
            return token
            
        except Exception as e:
            raise Exception(f"JWT编码失败: {str(e)}")
    
    @staticmethod
    def decode(token):
        """
        解码并验证JWT token
        
        参数:
            token: str - JWT token字符串
        
        返回:
            dict - 解码后的载荷数据
        
        异常:
            jwt.ExpiredSignatureError - token已过期
            jwt.InvalidTokenError - token无效或被篡改
        """
        try:
            # 从配置中获取密钥
            secret_key = current_app.config.get('JWT_SECRET_KEY', 'your-secret-key-change-in-production')
            
            # 解码token
            payload = jwt.decode(
                token,
                secret_key,
                algorithms=['HS256']
            )
            
            return payload
            
        except jwt.ExpiredSignatureError:
            raise Exception("Token已过期，请重新登录")
        except jwt.InvalidTokenError:
            raise Exception("Token无效或已被篡改")
        except Exception as e:
            raise Exception(f"JWT解码失败: {str(e)}")
    
    @staticmethod
    def generate_tokens(user_data):
        """
        生成访问token和刷新token
        
        参数:
            user_data: dict - 用户数据（如{'username': 'admin', 'user_id': 1}）
        
        返回:
            dict - {'access_token': '...', 'refresh_token': '...'}
        """
        # 生成访问token（30分钟有效）
        access_token = JWTUtil.encode(user_data, expire_minutes=30)
        
        # 生成刷新token（60分钟有效）
        refresh_payload = user_data.copy()
        refresh_payload['type'] = 'refresh'  # 标记为刷新token
        refresh_token = JWTUtil.encode(refresh_payload, expire_minutes=60)
        
        return {
            'access_token': access_token,
            'refresh_token': refresh_token
        }


